﻿#region License
/* 
Copyright 2008 William C. Pierce 

Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 

	http://www.apache.org/licenses/LICENSE-2.0 

Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
See the License for the specific language governing permissions and 
limitations under the License. 
*/
#endregion

namespace NHibernate.Proxy.Generator
{
	using System;
	using System.Collections;
	using System.Reflection;
	using Castle.DynamicProxy;
	using Engine;
	using Iesi.Collections.Generic;
	using Type;

	public class GeneratorProxyFactory : IProxyFactory
	{
		private readonly ProxyGenerator _proxyGenerator;
		private readonly IDictionary _proxies;

		public GeneratorProxyFactory(ProxyGenerator proxyGenerator, IDictionary proxies)
		{
			if( proxyGenerator == null )
			{
				throw new ArgumentNullException( "proxyGenerator" );
			}
			if( proxies == null )
			{
				throw new ArgumentNullException( "proxies" );
			}

			_proxyGenerator = proxyGenerator;
			_proxies = proxies;
		}

		public void PostInstantiate(string entityName, Type persistentClass, ISet<Type> interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType)
		{
			if ( persistentClass.IsGenericType ) return;

			int interfacesCount = interfaces.Count;
			bool isClassProxy = interfacesCount == 1;
			Type[] ifaces = new Type[interfacesCount];
			interfaces.CopyTo( ifaces, 0 );

			string proxyKey;

			if( isClassProxy )
			{
				proxyKey = persistentClass.FullName;
			}
			else
			{
				proxyKey = ifaces[0].FullName;
			}

			foreach (Type iface in ifaces)
			{
				proxyKey = string.Concat( proxyKey, "|", iface.FullName ); 
			}

			Type proxyType;
			if( isClassProxy )
			{
				proxyType = _proxyGenerator.ProxyBuilder.CreateClassProxy( persistentClass, ifaces, ProxyGenerationOptions.Default );
			}
			else
			{
				proxyType = _proxyGenerator.ProxyBuilder.CreateInterfaceProxyTypeWithoutTarget( ifaces[0], ifaces, ProxyGenerationOptions.Default );
			}

			_proxies[proxyKey] = proxyType;
		}

		public INHibernateProxy GetProxy(object id, ISessionImplementor session)
		{
			throw new NotImplementedException();
		}
	}
}